/**
 * Created On: Dec 23, 2012
 */
package com.athena.service.exam;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.athena.api.exam.IExamService;
import com.athena.dal.dao.GenericDao;
import com.athena.dal.entities.Examination;
import com.athena.dal.entities.Examination.ExamType;

/**
 * @author Ashish Kumar Sinha <aksinha.mail@gmail.com>
 * Version 1.0
 */
@Service("examService")
@Scope((BeanDefinition.SCOPE_SINGLETON))
public class ExamService implements IExamService {
	
	@Autowired
	private GenericDao genericDao;

	/* (non-Javadoc)
	 * @see com.athena.api.exam.IExamService#createOrUpdate(com.athena.dal.entities.Examination)
	 */
	@Override
	public Examination createOrUpdate(Examination exam) {
		if(genericDao != null) {
			return genericDao.createOrUpdate(exam);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see com.athena.api.exam.IExamService#create(int, int, com.athena.dal.entities.Examination.ExamType)
	 */
	@Override
	public Examination create(int subjectId, int minutes, ExamType examType) {
		if(genericDao != null) {
			Examination exam = new Examination(subjectId, minutes, examType);
			return genericDao.create(exam);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see com.athena.api.exam.IExamService#findForSubject(int)
	 */
	@Override
	public List<Examination> findForSubject(int subjectId) {
		if(genericDao != null){
			Map<String, Object> parameters = new HashMap<String, Object>();
			parameters.put("subjectId", subjectId);
			return genericDao.findAllByNameQuery(Examination.class, "Examination.findForSubject", parameters);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see com.athena.api.exam.IExamService#findForClass(int)
	 */
	@Override
	public Map<Integer, List<Examination>> findForClass(int classId) {
		List<Examination> allExams = null;
		if(genericDao != null){
			Map<String, Object> parameters = new HashMap<String, Object>();
			parameters.put("classId", classId);
			allExams = genericDao.findAllByNameQuery(Examination.class, "Examination.findForClass", parameters);
		}
		
		/*
		 *  populate subject and examination map from the list of all exams.
		 */
		return prepareSubjectExamMap(allExams);
	}

	/* (non-Javadoc)
	 * @see com.athena.api.exam.IExamService#findForFaculty(int)
	 */
	@Override
	public List<Examination> findForFaculty(int facultyId) {
		List<Examination> allExams = null;
		if(genericDao != null){
			Map<String, Object> parameters = new HashMap<String, Object>();
			parameters.put("facultyId", facultyId);
			System.out.println("Finding exams for faculty id: " + facultyId);
			allExams = genericDao.findAllByNameQuery(Examination.class, "Examination.findForFaculty", parameters);
			System.out.println("List of exams for faculty id: " + facultyId +" Exams:" + allExams);
		}
		
		/*
		 *  populate subject and examination map from the list of all exams.
		 */
		//return prepareSubjectExamMap(allExams);
		return allExams;
	}
	
	private Map<Integer, List<Examination>> prepareSubjectExamMap(List<Examination> allExams) {
		if(allExams == null || allExams.isEmpty()) { return null; }
		
		Map<Integer, List<Examination>> subjectExamMap = new HashMap<Integer, List<Examination>>();
		int currentSubjectId = -1;
		List<Examination> currentExamList = null;
		for (Examination examination : allExams) {
			if(examination != null) {
				if(currentSubjectId != examination.getSubjectId()) {
					if(currentSubjectId > 0 && currentExamList != null && !currentExamList.isEmpty()) {
						subjectExamMap.put(currentSubjectId, currentExamList);
					}
					currentExamList = null;
				}
				// same subject Id. Just add this instance into the list.
				if(currentExamList == null) {
					currentExamList = new ArrayList<Examination>();
				}
				currentExamList.add(examination);
				currentSubjectId = examination.getSubjectId();
			}
		}
		
		if(currentSubjectId > 0 && currentExamList != null && !currentExamList.isEmpty()) {
			subjectExamMap.put(currentSubjectId, currentExamList);
		}
		return subjectExamMap;
	}

	/**
	 * @return the genericDao
	 */
	public GenericDao getGenericDao() {
		return genericDao;
	}

	/**
	 * @param genericDao the genericDao to set
	 */
	public void setGenericDao(GenericDao genericDao) {
		this.genericDao = genericDao;
	}

}
